package aspect.example;
import aspect.entity.behavior.Behavior;
import static aspect.core.AspectLauncher.*;
import aspect.core.AspectRenderer;
import static aspect.core.AspectRenderer.*;
import aspect.core.ScreenViewpoint;
import static aspect.resources.Resources.*;
import aspect.util.Vector2;
import aspect.util.Vector3;
import aspect.entity.Entity;
import aspect.event.KeyEvent;
import aspect.event.MouseEvent;
import aspect.physics.dynamics.Force;
import aspect.physics.dynamics.PointGravity;
import aspect.physics.RigidBody;
import aspect.physics.Time;
import aspect.render.Material;
import aspect.render.VBO2D;
import aspect.render.ViewModel;
import java.io.File;
import org.lwjgl.input.Keyboard;
import static org.lwjgl.opengl.GL11.*;
public class A2DDemo extends Behavior {
private Entity ship;
private ScreenViewpoint viewpoint;
private Entity earth;
private Entity moon;
private float angle;
private Force earthGravity;
private Force moonGravity;
private ViewModel background;
private Material yesThrust;
private Material noThrust;
private boolean thrusters = false;
private boolean hud = false;
public static void main(String[] args) {
run(800, 600, false, 60, new A2DDemo());
printFPS(1000);
}
@Override
public void onAdd() {
Material earthImage = new Material(loadTexture(new File("textures/earth.png")));
float earthWidth = 6378.1e3f * 2;
ViewModel earthSprite = ellipse(earthImage, earthWidth, earthWidth, 100);
earth = new Entity(earthSprite);
earth.pos = new Vector3(getCanvasWidth() / 4, getCanvasHeight() / 4, 0);
earth.addBehavior(new RigidBody());
earth.rigidBody().mass = 5.97219e24f;
Material moonImage = new Material(loadTexture(new File("textures/moon.png")));
float moonWidth = 1737.4e3f * 2;
ViewModel moonSprite = ellipse(moonImage, moonWidth, moonWidth, 100);
moon = new Entity(moonSprite);
moon.pos = new Vector3(earth.pos.x - 384400e3f, earth.pos.y);
moon.addBehavior(new RigidBody());
moon.rigidBody().mass = 7.34767309e22f;
yesThrust = new Material(loadTexture("nothrust", new File("textures/ship.png")));
yesThrust.setTextureFilter(Material.Filter.MIPMAP, Material.Filter.NEAREST);
noThrust = new Material(loadTexture("thrust", new File("textures/ship_thrust.png")));
noThrust.setTextureFilter(Material.Filter.MIPMAP, Material.Filter.NEAREST);
ViewModel model = rect2D(noThrust, 37.5f, 50f);
ship = new Entity(model);
ship.pos = new Vector3(earth.pos.x, earth.pos.y + earthWidth / 2 + 300e3f);
ship.addBehavior(new RigidBody());
ship.rigidBody().mass = 78e3f;
ship.rigidBody().velocity.x = 7700f;
earthGravity = new PointGravity(earth);
moonGravity = new PointGravity(moon);
ship.rigidBody().addForce(earthGravity);
ship.rigidBody().addForce(moonGravity);
//earth.rigidBody().addForce(moonGravity);
//moon.rigidBody().addForce(earthGravity);
background = rect2D(new Material(loadTexture(new File("textures/background.png"))), 4, 3, 800, 600);
viewpoint = new ScreenViewpoint(Vector2.zero(), 1 / 32768f, 0) {
@Override
public Vector2 cameraPosition() {
return ship.pos.xy();
}
};
setCameraViewpoint(viewpoint);
addKeyListener(this);
addMouseListener(this);
moon.rigidBody().velocity.y = 1e3f;
}
private String formatTime(long millis) {
int days = (int) (millis / (24 * 3600_000));
millis %= (24 * 3600_000);
int hours = (int) (millis / 3600_000);
millis %= 3600_000;
int minutes = (int) (millis / 60_000);
millis %= 60_000;
int seconds = (int) (millis / 1000);
millis %= 1000;
return days + ":" + hours + ":" + minutes + ":" + seconds + ":" + millis;
}
@Override
public void update() {
moon.update();
earth.update();
ship.update();
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT) && Time.speed <= 4) {
angle -= 90 * Time.deltaTime();
}
if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT) && Time.speed <= 4) {
angle += 90 * Time.deltaTime();
}
ship.ang.roll = -ship.rigidBody().velocity.xy().dir() - angle;
if (thrusters) {
RigidBody rb = ship.rigidBody();
rb.impel(Vector2.fromAngle(-ship.ang.roll, 60e3f).asXY());
}
if (Vector3.distance(ship.pos, earth.pos) < 90 || Vector3.distance(ship.pos, moon.pos) < 70) {
//onAdd();
}
//System.out.println(Vector3.divide(ship.rigidBody().netForce(), ship.rigidBody().mass));
}
@Override
public void keyEvent(KeyEvent evt) {
if (evt.key == Keyboard.KEY_T && evt.type) {
hud = !hud;
}
if (evt.key == Keyboard.KEY_F) {
System.out.println("Current Time: " + formatTime(Time.frameTimeMillis()));
}
if (evt.key == Keyboard.KEY_LBRACKET && evt.type) {
Time.speed /= 2;
}
if (evt.key == Keyboard.KEY_RBRACKET && evt.type) {
Time.speed *= 2;
}
if (evt.key == Keyboard.KEY_SPACE && evt.type) {
thrusters = !thrusters;
if (thrusters) {
ship.getBehavior(VBO2D.class).setMaterial(yesThrust);
} else {
ship.getBehavior(VBO2D.class).setMaterial(noThrust);
}
}
}
@Override
public void mouseEvent(MouseEvent evt) {
float z = evt.wheel / 480f;
viewpoint.scale *= Math.pow(2, z);
/*
if (Mouse.isButtonDown(0)) {
viewpoint.pos.x -= evt.dx / viewpoint.scale;
viewpoint.pos.y -= evt.dy / viewpoint.scale;
}
*/
}
@Override
public void render() {
AspectRenderer.setRenderMode(RenderMode.ORTHOGONAL);
loadIdentity();
pushMatrix();
translate(new Vector3(getCanvasWidth() / 2, getCanvasHeight() / 2));
background.render();
popMatrix();
setupCamera2D(viewpoint);
earth.render();
moon.render();
ship.render();
if (hud) {
RigidBody rb = ship.rigidBody();
Vector2 v = Vector2.fromAngle(-ship.ang.roll, 50 / viewpoint.scale);
Vector2 a1 = Vector2.fromAngle(-ship.ang.roll + 140, 10 / viewpoint.scale);
Vector2 a2 = Vector2.fromAngle(-ship.ang.roll - 140, 10 / viewpoint.scale);
glColor3f(1, 0, 0);
glBegin(GL_LINES);
glVertex2f(ship.pos.x, ship.pos.y);
glVertex2f(ship.pos.x + v.x, ship.pos.y + v.y);
glVertex2f(ship.pos.x + v.x, ship.pos.y + v.y);
glVertex2f(ship.pos.x + v.x + a1.x, ship.pos.y + v.y + a1.y);
glVertex2f(ship.pos.x + v.x, ship.pos.y + v.y);
glVertex2f(ship.pos.x + v.x + a2.x, ship.pos.y + v.y + a2.y);
glEnd();
Vector3 forceVector = rb.netForce();
glColor3f(0, 0, 1);
glBegin(GL_LINES);
glVertex2f(ship.pos.x, ship.pos.y);
glVertex2f(ship.pos.x + forceVector.x, ship.pos.y + forceVector.y);
glEnd();
glColor3f(0, 1, 0);
glBegin(GL_LINE_STRIP);
Vector3 curVel = rb.velocity.copy();
Vector3 curPos = ship.pos.copy();
glVertex2f(curPos.x, curPos.y);
float tick = 5f;
boolean readyToStop = false;
for (float t = 0; t < 8000; t += tick) {
Entity e = new Entity();
e.addBehavior(new RigidBody(curVel, Vector3.zero()));
e.rigidBody().addForce(moonGravity);
e.rigidBody().addForce(earthGravity);
e.pos = curPos;
Vector3 realAcc = rb.acceleration.plus(Vector3.divide(e.rigidBody().netForce(), e.rigidBody().mass));
Vector3 velOld = curVel;
curVel = curVel.plus(realAcc.times(tick));
curPos = curPos.plus(Vector3.multiply(Vector3.add(Vector3.multiply(velOld, tick), Vector3.multiply(curVel, tick)), 0.5f));
glVertex2f(curPos.x, curPos.y);
if (Vector2.toAngle(earth.pos.xy(), ship.pos.xy()) < Vector2.toAngle(earth.pos.xy(), curPos.xy())) {
if (readyToStop) {
break;
}
} else {
readyToStop = true;
}
}
glEnd();
}
}
}